#define _CRT_SECURE_NO_WARNINGS 1

#include <cstdlib>
#include <cassert>
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
#include <list>

using namespace std;

namespace xyx
{
	class string
	{
	public:
		typedef char* iterator;
		iterator begin()
		{
			return _str;
		}

		iterator end()
		{
			return _str + _size;
		}

		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			cout << "string(char* str)" << endl;

			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

		// s1.swap(s2)
		void swap(string& s)
		{
			::swap(_str, s._str);
			::swap(_size, s._size);
			::swap(_capacity, s._capacity);
		}

		// 拷贝构造
		string(const string& s)
			:_str(nullptr)
		{
			cout << "string(const string& s) -- 深拷贝" << endl;

			string tmp(s._str);
			swap(tmp);
		}

		// 移动构造
		string(string&& s)
			:_str(nullptr)
		{
			cout << "string(string&& s) -- 移动拷贝" << endl;

			swap(s);
		}

		// 赋值重载
		string& operator=(const string& s)
		{
			cout << "string& operator=(string s) -- 深拷贝" << endl;
			string tmp(s);
			swap(tmp);

			return *this;
		}

		// 移动赋值重载
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移动拷贝" << endl;
			swap(s);

			return *this;
		}


		~string()
		{
			delete[] _str;
			_str = nullptr;
		}

		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}

		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				strcpy(tmp, _str);
				delete[] _str;
				_str = tmp;

				_capacity = n;
			}
		}

		void push_back(char ch)
		{
			if (_size >= _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
				reserve(newcapacity);
			}

			_str[_size] = ch;
			++_size;
			_str[_size] = '\0';
		}

		//string operator+=(char ch)
		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}

		const char* c_str() const
		{
			return _str;
		}
	private:
		char* _str;
		size_t _size;
		size_t _capacity; // 不包含最后做标识的\0
	};
}

#include "list.h"

//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const 左值引用" << endl; }
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const 右值引用" << endl; }
//
//template<typename T>
//void PerfectForward(T&& t)
//{
//	//完美转发
//	//t是左值引用就是左值引用
//	//t是右值引用就是右值引用
//	Fun(forward<T>(t));
//}
//
//int main()
//{
//	PerfectForward(10); //右值
//	int a;
//	PerfectForward(a);//左值
//	PerfectForward(std::move(a)); //右值
//	const int b = 8;
//	PerfectForward(b);//const 左值
//	PerfectForward(std::move(b));// const 右值
//	return 0;
//}

//template<typename T>
//void PerfectForward(T&& t)
//{
//	Fun(t);
//}
//
//int main()
//{
//	int a;
//	PerfectForward(std::move(a)); 
//	const int b = 8;
//	PerfectForward(std::move(b));
//
//	int&& r = move(a);
//	cout << &r << endl;
//	return 0;
//}

//int main()
//{
//	xyx::list<xyx::string> lt;
//	xyx::string s1("xxxxxxxx");
//	lt.push_back(s1);
//	cout << endl;
//
//	xyx::string s2("xxxxxxxx");
//	lt.push_back(move(s2));
//	cout << endl;
//
//	lt.push_back("xxxxxxxxxxxxx");
//	cout << endl;
//	return 0;
//}

//xyx::string func()
//{
//	xyx::string str("hello world");
//	// ...
//
//	return str;
//}
//
//int main()
//{
//	xyx::string s1 = func();
//	
//	//xyx::string s2;
//	//s2 = func();
//
//	return 0;
//}

//int main()
//{
//	string s1("hello world");
//	string cp1 = s1;
//	move(s1);
//	string cp2 = s1;
//	string cp3 = move(s1);
//
//
//	return 0;
//}

////func构成函数重载
//void func(const int& r)
//{
//	cout << "void func(const int& r)" << endl;
//}
//
//void func(int&& r)
//{
//	cout << "void func(int&& r)" << endl;
//}
//
//int main()
//{
//
//	return 0; 
//}


//int sum(int x, int y)
//{
//	return x + y;
//}
//
//int main()
//{
//	//左值引用
//	int a = 10;
//	int& r1 = a;
//
//	//const左值可以引用右值
//	const int& r2 = 20;
//
//	//右值引用
//	int&& r3 = 10;
//
//	//右值引用move后的左值
//	int&& r4 = move(r1);
//
//	return 0;
//}

//int main()
//{	
//	//左值部分
//	int a = 10;
//	int b = a;
//	int* c = new int;
//	
//	//这里的"hello world"虽然是常量字符串
//	//但是它是左值，因为可以对它进行取地址操作
//	const char* pc = "hello world";
//
//	//右值部分
//	20;
//	a + b;
//	sum(a, b);//传值返回，返回得是临时对象的拷贝
//
//	return 0;
//}


//void func(int* p)
//{}
//
//void func(int i)
//{}
//
//int main()
//{
//	int* p = NULL;
//	func(p);// func(0)
//}

//template<class FUNC>
//class A
//{
//private:
//    FUNC _func;
//};
//
//int main()
//{
//    //用于自动推导出函数指针类型
//    auto f = malloc;
//    cout << typeid(f).name() << endl;
//
//    //typeid().name 只是返回类型名称的字符串，不能用于定义变量
//    //typeid(f).name pf;
//
//    decltype(f) pf; //通过变量名的类型推导出类型，用于定义变量
//     
//    A<decltype(f)> aa; // 可以用于推导变量名的结果，用作模板实参
//
//    return 0;
//}

//namespace xyx
//{
//
//    template<class T>
//    class initializer_list
//    {
//        T* start;
//        T* finish;
//    };
//
//}
//
//struct A
//{
//    A(int x, int y)
//        :_x(x)
//        , _y(y)
//    {}
//
//    int _x;
//    int _y;
//};

//int main()
//{
//    map<string, string> dict = { {"hello", "你好"}, {"world", "世界"} };
//    //map<string, string>::iterator it = dict.begin();
//    //自动推导类型为迭代器
//    auto it = dict.begin();
//
//    //用于自动推导出函数指针类型
//    auto f = malloc;
//    cout << typeid(f).name() << endl;
//
//    //范围for中 根据范围推导类型
//    vector<string> v = { "hello", "world" };
//    for (auto s : v)
//        cout << s << endl;
//
//    //typeid().name 只是返回类型名称的字符串，不能用于定义变量
//    //typeid(f).name pf;
//
//    decltype(f) pf;
//
//
//    return 0;
//}

//int main(int argc, const char * argv[])
//{
//    //对于内置类型
//    int a = 10;
//    int b{20};
//    
//    int arr1[] = {1,2,3};
//    int arr2[]{3,4,5};
//    
//    //对于自定义类型
//    //去调用它的构造初始化
//    A aa = {1,2}; //多参数的隐式类型转换
//    A bb{3,4};
//    
//    //列表初始化也可以用于初始化new的结果
//    int* pi = new int[3]{1,2,3};
//    A* pAarr = new A[2]{{4,5},{6,7}};
//    
//    return 0;
//}


//int main(int argc, const char * argv[])
//{
//    int a = 10;
//    int arr[] = {1,2,3};
//    A aa = {1,2};
//    return 0;
//}

struct Goods
{
	string _name;  // 名字
	double _price; // 价格
	int _evaluate; // 评价

	Goods(const char* str, double price, int evaluate)
		:_name(str)
		, _price(price)
		, _evaluate(evaluate)
	{}
};

struct GoodsPriceLess
{
	bool operator()(const Goods& g1, const Goods& g2)
	{
		return g1._price < g2._price;
	}
};

//int main()
//{
//	vector<Goods> v = { {"苹果", 2.5, 3},{"香蕉", 1.0, 4} ,{"梨", 3.2, 5} };
//	//sort(v.begin(), v.end(), GoodsPriceLess()); //仿函数
//
//	//[](const Goods& g1, const Goods& g2){ return g1._price > g2._price; }
//	//->类型可以省略，编译器可以通过return的类型推导
//	auto GoodsPriceGreater = [](const Goods& g1, const Goods& g2)->bool { return g1._price > g2._price; };
//	sort(v.begin(), v.end(), GoodsPriceGreater);
//
//	//lambda表达式可以直接传参
//	sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){ return g1._price < g2._price; });
//	return 0;
//}

void test()
{
	cout << "void test()" << endl;
}

//int main()
//{
//	int a = 10, b = 20;
//	auto add1 = [](int x, int y) { return x + y;};
//	cout << add1(a, b) << endl;
//
//	auto swap = [](int& x, int& y) {
//		int tmp = x;
//		x = y;
//		y = tmp;
//
//		//add1(x, y);//[]默认情况下局部lambda对象不能调用。 
//		test(); // []默认情况下可以调用全局函数
//		};
//
//	return 0;
//}

//int main()
//{
//	//int x = 10, y = 20;
//
//	////默认捕获的变量具有常量属性，不能修改
//	////auto swap = [x,y]() {
//	////	int tmp = x;
//	////	x = y;
//	////	y = tmp;
//	////	};
//	//
//	////使用mutable关键字让捕获的x 和 y可以修改
//	//auto swap1 = [x,y]()mutable {
//	////这里捕获的是值，即 外部定义的x y 的拷贝
//	////这里的交换逻辑不会改变外部定义的x y
//	//int tmp = x;
//	//x = y;
//	//y = tmp;
//	//};
//
//	//swap1();
//
//	////这里是以引用的方式捕获x 和 y
//	//auto swap2 = [&x, &y]() {
//	////以引用的方式捕获,修改可以影响外面的x y
//	//int tmp = x;
//	//x = y;
//	//y = tmp;
//	//};
//
//	//swap2();
//
//	int a = 0;
//	int b = 0;
//	int c = 0;
//	int d = 0;
//	const int e = 0;
//	
//	//全部以引用方式捕捉
//	auto func1 = [&]
//	{
//		
//	};
//
//	//全部以引用方式捕捉，b除外
//	//b用传值方式捕捉
//	auto func2 = [&]
//		{
//			a++;
//			//b是常量
//			c++;
//			d++;
//			//e 也是常量
//		};
//
//	return 0;
//}

//class Rate
//{
//public:
//	Rate(double rate) : _rate(rate)
//	{}
//
//	double operator()(double money, int year)
//	{
//		return money * _rate * year;
//	}
//
//private:
//	double _rate;
//};
//
//int main()
//{
//	// 函数对象
//	double rate = 0.49;
//	Rate r1(rate);
//	r1(10000, 2);
//
//	// lambda
//	auto r2 = [=](double monty, int year)->double {return monty * rate * year; };
//	r2(10000, 2);
//
//	return 0;
//}

//void printlist()
//{
//	//递归结束条件
//	//可变参数包为空就会进入这里
//	cout << endl;
//}
//
//template<class T, class ...Args>
//void printlist(T val, Args... args)
//{
//	//依次取可变参数包里的参数
//	//然后用T实例化对象来推导可变参数包里的内容
//	//然后打印出来
//	cout << val << " ";
//	printlist(args...);//继续递归调用
//}
//
//template<class ...Args>
//void printlist(Args... args)//args 表示0-n个可变参数包
//{
//	printlist(args...);//递归调用void printlist(T val, Args... args)
//}
//
//int main()
//{
//	printlist(1);
//	printlist(1,2,3);
//	printlist(1,2,3,5.4, "hello");
//	return 0;
//}

//
//template <class T>
//void PrintArg(T t)
//{
//	cout << t << " "; // 函数接受一个参数 t，并将其打印出来，后面跟一个空格。
//}
////展开函数
//template <class ...Args>
//void ShowList(Args... args)//模板参数包 Args... 表示可以接受任意数量和类型的参数。
//{
//	//函数内部定义了一个整数数组 arr，并使用初始化列表和逗号表达式来展开参数包。
//	// 对于每个参数 args，先调用 PrintArg(args) 打印参数，然后将结果与 0 组成一个逗号表达式，并将其作为数组元素的初始化值。
//	int arr[] = { (PrintArg(args), 0)... }; 
//	cout << endl;
//}
//
//int main()
//{
//	ShowList(1);
//	ShowList(1, 2.2, 3);
//	ShowList(1, 3.1, "hello world");
//	return 0;
//}

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{
		cout << "Date构造" << endl;
	}

	Date(const Date& d)
		:_year(d._year)
		, _month(d._month)
		, _day(d._day)
	{
		cout << "Date拷贝构造" << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};


template <class ...Args>
Date* Create(Args... args)
{
	Date* ret = new Date(args...);

	return ret;
}

//int main()
//{
//	Date* pd1 = Create();
//	Date* pd2 = Create(2024);
//	Date* pd3 = Create(2024, 1);
//	Date* pd4 = Create(Date(2024,10,22));
//
//	return 0;
//}

//int main()
//{
//	//std::list<Date> lt;
//	//lt.push_back(Date(2024, 10, 22));
//	//lt.emplace_back(2024, 10, 22);
//
//	xyx::list<xyx::string> lt;
//	lt.push_back(xyx::string("hello"));
//	lt.emplace_back ("world");
//
//	return 0;
//}


//class Person
//{
//public:
//	Person(const char* name = "", int age = 0)
//		:_name(name)
//		, _age(age)
//	{}
//
//	/*Person(const Person& p)
//		:_name(p._name)
//		,_age(p._age)
//	{}*/
//
//	/*Person& operator=(const Person& p)
//	{
//		if(this != &p)
//		{
//			_name = p._name;
//			_age = p._age;
//		}
//		return *this;
//	}*/
//
//
//	//~Person()
//	//{}
//	
//	Person(const Person& p) = delete;
//	
//
//private:
//	xyx::string _name;
//	int _age;
//};
//
//int main()
//{
//	Person p1;
//	Person p2 = p1;
//
//
//	return 0;
//
//}
#include <functional>

//template<class F, class T>
//T useF(F f, T x)
//{
//	static int count = 0;
//	cout << "count:" << ++count << endl;
//	cout << "count:" << &count << endl;
//	return f(x);
//}
//double f(double i)
//{
//	return i / 2;
//}
//struct Functor
//{
//	double operator()(double d)
//	{
//		return d / 3;
//	}
//};
//int main()
//{
//	//// 函数名
//	//cout << useF(f, 11.11) << endl;
//	//// 函数对象
//	//cout << useF(Functor(), 11.11) << endl;
//	//// lamber表达式
//	//cout << useF([](double d)->double { return d / 4; }, 11.11) << endl;
//
//	// 包装器 -- 解决了描述可调用对象的类型问题
//	function<double(double)> f1 = f;
//	function<double(double)> f2 = [](double d)->double { return d / 4; };
//	function<double(double)> f3 = Functor();
//
//	//vector<function<double(double)>> v = { f1, f2, f3 };
//	vector<function<double(double)>> v = { f, [](double d)->double { return d / 4; }, Functor() };
//
//	double n = 3.3;
//	for (auto f : v)
//	{
//		cout << useF(f, 11.11) << endl;
//	}
//
//	return 0;
//}

//int sub(int x, int y)
//{
//	return x - y;
//}
//
//double add(int x, double rate, int y)
//{
//	return (x + y) * rate;
//
//}
//
//int main()
//{
//	//占位符的值不是按照参数列表的对应位置，而是按照相对顺序
//	auto func1 = bind(add, placeholders::_1, 2.1, placeholders::_2);
//	cout << func1(1, 3) << endl;
//
//	//placeholders::_1 表示第一个参数的占位符
//	//可以通过调整占位符的顺序来决定新绑定的可调用对象的传参顺序
//	//function<int(int, int)> func1 = bind(sub, placeholders::_1, placeholders::_2);
//	//cout << func1(20, 10) << endl;;
//
//	//auto func2 = bind(sub, placeholders::_2, placeholders::_1);
//	//cout << func2(20, 10) << endl;
//	
//}

class SubType
{
public:
	int sub(int x, int y)
	{
		return x - y;
	}

	static int ssub(int x, int y, int z)
	{
		return x - y - z;
	}
};

int main()
{
	//绑定非静态成员函数，需要 & + 指明类域 + 穿匿名对象或者传一个类对象
	SubType st;
	auto func1 = bind(&SubType::sub, SubType(), placeholders::_1, 2.1, placeholders::_2);
	auto func2 = bind(&SubType::sub, st, placeholders::_1, 2.1, placeholders::_2);

	//绑定静态成员函数，指明指明类域即可
	// & 可加可不加
	auto func3 = bind(&SubType::ssub, placeholders::_1, 2.1, placeholders::_2);

	return 0;
}